<html>
<head><title>Planned changes to the plug-in registry APIs and their implementation</title></head>
<body>
<h1>Planned changes to the plug-in registry API and implementation</h1>
<EM>Last update: April 23, 2003</EM> 
<h4>Summary of planned changes:</h4>

<ul>
<li><a href="#fragments_api">Provide API for fragments in the platform registry</a></li>
<li><a href="#fragments_nls">Provide modular way to externalize strings in fragment.xml</a></li>
<li><a href="#contributed_elements">Provide API for checking if a given plug-in descriptor element has been contributed by a fragment</a></li>
</ul>

<h3><a name="fragments_API">Provide API for fragments in the platform registry</a></h3>

<h4>Related bugs:</h4>
<ul>
	<li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14460">Bug 14460</a> 
	- [runtime] No APIs for obtaining fragments installation directory for a given plugin</li>
	<li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20499">Bug 20499</a> 
	- Need a public API similer to FragmentDescriptor#getInstallURL()</li>
</ul>

<p>The platform registry API, whose starting point is the <code>Platform.getPluginRegistry()</code>, 
provides access to descriptors for the plug-ins in the registry but not for the fragments. Fragments 
provide objects (pre-requisites, libraries, extensions, extension points) that are combined with those 
in the plug-in they associate to during the registry resolution process.</p>

<h4>Requisites:</h4><ul>
	<li>the install URL for a fragment is needed: the general use case is that plug-in's/fragment's code 
	need to know the location of specific files contributed by fragments.</li>
</ul>

<h4>Proposed solution:</h4><ul>
	<li>add new API interface <code>org.eclipse.core.runtime.IFragmentDescriptor</code>;</li>
	<li>add new API method <code>URL[] getInstallURL()</code> to 
	<code>IFragmentDescriptor</code>;</li>
	<li>add new API methods <code>IFragmentDescriptor[] getFragments()</code> and 
	<code>IFragmentDescriptor getFragment(String id)</code> 
	to <code>IPluginDescriptor</code>.</li>
</ul>

<h4>Notes:</h4>
<p>Currently, clients rely on the fact that the implementations for plug-in registry interfaces in 
<code>org.eclipse.core.runtime</code> extend the corresponding model classes in 
<code>org.eclipse.core.runtime.model</code>. This is not specified - we should document if this
is expected or disallowed (and we would be able to change the implementation hierarchy for those classes).
</p>

<h3><a name="fragments_NLS">Provide modular way to externalize strings in fragment.xml</a></h3>

<h4>Related bugs:</h4><ul>
	<li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18617">Bug 18617</a> 
	- [runtime] modular way to externalize strings in fragment.xml</li>
	<li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18339">Bug 18339</a> 
	- API clarification: where to find translations for labels and provider names for plug-ins and fragments</li>
	<li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31094">Bug 31094</a> 
	- [About] show real plugin names in 'About'</li>
	<li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31596">Bug 31596</a> 
	- fragment_*.properties should participate in the plugin resource bundle find path</li>
	<li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35992">Bug 35992</a> 
	- [runtime] Fragments should know their plug-ins</li>
</ul>

<p>From Jeem's comments in bug 18617:</p>

<p><cite>&quot;Externalized strings for all plug-in fragments must be placed in the
their plug-in's &quot;plugin.properties&quot; resource bundle. In other words,
a fragment's strings must be merged into the main plug-in's file.
Although this is not very modular, it does at least allow strings
to be externalized and translated.&quot;</cite></p>


<h4>Requisites:</h4><ul>
  <li>UI needs to translate fragment name and fragment's provider name to show in the about dialog (bug 31094).</li>
  <li>fragments should be able to have their externalized strings provided by 
    themselves, by the plug-in, or by other fragments (bugs 18617, 31596).</li>	
</ul>

<h4>Proposed solution:</h4>

<p>From Jeem's comments in bug 18617:</p>

<p><cite>&quot;In order to dovetail with existing mechanisms, each fragment must have its
own *.properties files. It would be a non-started if these *.properties
files all had the same name (e.g., &quot;fragment.properties&quot;), since all 
OS-specific fragments would collide on this name making it impossible
to spuuly translations for any of they. It is therefore essential that each
fragment get a distinctively named *.properties file. The simplest way to
arrange this is to add a new attribute to the &lt;fragment&gt; element
to specific the name of the properties file; e.g.,
   resource-bundle=&quot;win32fragment&quot;
would mean that the file named &quot;win32fragment.properties&quot; would contain
the translated strings (&quot;win32fragment&quot; is the base name of the property
resource bundle, in Java parlance). </cite></p>

<p><cite>The attribute would also be meaningful on a &lt;plugin&gt; element. If the attribute 
is omitted, the default resource bundle base name is &quot;plugin&quot;. This makes
the new story upwards compatible with the current story where all &quot;%vars&quot; 
in the plugin.xml and in all the fragment.xmls get resolved in the plug-in's 
property resource bundle &quot;plugin.properties&quot;.&quot;</cite></p>

<p>Methods in the model objects return strings as they appear in the manifest file.
Clients that want those strings properly translated should (as suggested in bug 18339) 
call <code>IPluginDescriptor#getResolvedString(String)</code>
and the new proposed method <code>IFragmentDescriptor#getResolvedString(String)</code>.</p>

<p>Also, since the &quot;.properties&quot; file may be anywhere in th plug-in's 
  classpath, the fragment descriptor implementation should ask its plug-in descriptor 
  for the path where to look for it (what requires a fix for bug 35992).</p>
<ul>
	
  <li>add new API methods <code>String getLabel()</code>, <code>String getProviderName()</code> 
    and <code>String getResourceString(String)</code> to <code>IFragmentDescriptor</code> 
    - these methods would do the same thing as their counterparts in <code>IPluginDescriptor</code> 
    but would take into consideration the bundle built on the corresponding <code>fragment.properties</code> 
    file;</li>
  <li>the internal implementation for <code>IPluginDescriptor</code> should be 
    refactored in order to share the translation funcionality with the new method 
    <code>getResourceString(String)</code> to be implemented by <code>FragmentDescriptor</code>.</li>
</ul>

<h3><a name="contributed_elements">Provide API for checking if a given plug-in descriptor element has been contributed by a fragment</a></h3>

<h4>Related bugs:</h4><ul>
	<li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23165">Bug 23165</a> 
	- [runtime] Plug-in model objects should know where they are coming from</li>
</ul>

<p>Fragments provide objects (pre-requisites, libraries, extensions, extension 
  points) that are combined with those in the plug-in they associate to during 
  the registry resolution process.</p>

<h4>Requisites:</h4><ul>
	
  <li>it should be possible to tell apart elements provided by plug-ins from those 
    contributed by fragments: PDE currently casts the <code>IPluginRegistry</code> 
    and <code>IPluginDescriptor</code> to their corresponding model objects (already 
    in memory) to avoid reparsing the manifests. But since the registry is already 
    resolved, PDE does not know which elements were originally part of a plug-in. 
    A simple <code>isFragmentContributed()</code> (in a sense that it is contributed 
    by a fragment) in library, pre-requisite, extension and extension point model 
    objects would be enough. To reduce memory footprint, the <code>PluginModelObject.flags</code> 
    field could be used to store this information.</li>
</ul>

<h4>Proposed solution:</h4><ul>
	<li>add new API class <code>FragmentContributableModel</code> (sub-class of <code>PluginModelObject</code>);</li>
	<li>add new API methods <code>boolean FragmentContributableModel.isFragmentContributed()</code> and <code>void FragmentContributableModel.markFragmentContributed()</code>;</li>	
	<li>make <code>LibraryModel</code>, <code>PrerequisiteModel</code>, <code>ExtensionModel</code> and <code>ExtensionPointModel</code> sub-classes of <code>FragmentContributableModel</code>;</li>
  <li>make <code>PluginModelObject.flags</code> package-private so they can be 
    accessed from <code>FragmentContributableModel</code>.</li>		
</ul>

</body>
</html>